package com.authine.cloudpivot.ext.controller.archives;

import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.ext.Utils.CustomSchemaCode;
import com.authine.cloudpivot.ext.service.CloudSqlService;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * @author fengjie
 * @version 1.0.0
 * @ClassName ArchivesController
 * @Description 档案点检记录
 * @createTime 2023/2/2 8:43
 */
@RestController
@RequestMapping("/public/archives")
@Slf4j
public class ArchivesController extends BaseController {
    @Autowired
    CloudSqlService sqlService;

    /**
     * 【总公司级档案总公司落实点检汇总记录】审批完成后，数据同步到【总公司级档案总公司落实点检汇总记录 基础表】
     */
    @RequestMapping("finishToOfficeArchivesBase1")
    public void finishToOfficeArchivesBase1(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.HEAD_OFFICE_ARCHIVES_1, bizId);
        // 相关档案明细表
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.HEAD_OFFICE_ARCHIVES_DETAIL);

        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        //
        for (Map<String, Object> map : list) {
            try {/**/
                Map<String, Object> data = fileInfoBaseMap(bizObject, map, approval);
                // 判断是否已存在
                String id = existsBizObject(data, CustomSchemaCode.OFFICE_ARCHIVES_BASE_1);
                if (StringUtils.isNotEmpty(id)) {
                    data.put("id", id);
                }
                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.OFFICE_ARCHIVES_BASE_1, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("总公司级档案总公司落实点检汇总记录 基础表数据新增成功");

                // 删除下级档案
                String fileCodeStr = map.get("fileCodeStr").toString();
                String sql = "delete from i54le_office_archives_base_1 where id in (select a.id from ( select id from i54le_office_archives_base_1\n" +
                        "where fileCodeStr like '" + fileCodeStr + "%' and fileCodeStr != '"+fileCodeStr+"'\n" +
                        ") as a)";
                sqlService.update(sql);

                // 调用存储过程
                callHeadOfficeArchives1Process(id);
            } catch (Exception e) {
                log.info("总公司级档案总公司落实点检汇总记录 基础表数据维护失败，报错信息：{}", e.getMessage());
                log.info("总公司级档案总公司落实点检汇总记录 基础表数据操作失败 档案代码={}", map.get("fileCodeStr"));
            }
        }
    }

    /**
     * 【总公司级档案公司落实点检汇总记录】审批完成后，数据同步到【总公司级档案公司落实点检汇总记录 基础表】
     */
    @RequestMapping("finishToOfficeArchivesBase2")
    public void finishToOfficeArchivesBase2(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.HEAD_OFFICE_ARCHIVES_2, bizId);
        // 相关档案明细表
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.HEAD_OFFICE_ARCHIVES_DETAIL2);

        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        //
        for (Map<String, Object> map : list) {
            try {/**/
                Map<String, Object> data = fileInfoBaseMap(bizObject, map, approval);
                // 判断是否已存在
                String id = existsBizObject(data, CustomSchemaCode.OFFICE_ARCHIVES_BASE_2);
                if (StringUtils.isNotEmpty(id)) {
                    data.put("id", id);
                }
                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.OFFICE_ARCHIVES_BASE_2, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("总公司级档案公司落实点检汇总记录 基础表数据新增成功");

                // 删除下级档案
                String fileCodeStr = map.get("fileCodeStr").toString();
                String sql = "delete from i54le_office_archives_base_2 where id in (select a.id from ( select id from i54le_office_archives_base_2\n" +
                        "where fileCodeStr like '" + fileCodeStr + "%' and fileCodeStr != '"+fileCodeStr+"'\n" +
                        ") as a)";
                sqlService.update(sql);

                // 调用存储过程
                callHeadOfficeArchives2Process(id);
            } catch (Exception e) {
                log.info("总公司级档案公司落实点检汇总记录 基础表数据维护失败，报错信息：{}", e.getMessage());
                log.info("总公司级档案公司落实点检汇总记录 基础表数据操作失败 档案代码={}", map.get("fileCodeStr"));
            }
        }
    }

    /**
     * 【公司级档案落实点检汇总记录】审批完成后，数据同步到【公司级档案落实点检汇总记录 基础表】
     */
    @RequestMapping("finishToCompanyArchivesBase")
    public void finishToCompanyArchivesBase(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.COMPANY_ARCHIVES, bizId);
        // 相关档案明细表
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.COMPANY_ARCHIVES_DETAIL);

        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        //
        for (Map<String, Object> map : list) {
            try {/**/
                Map<String, Object> data = fileInfoBaseMap(bizObject, map, approval);
                data.put("company", map.get("comp"));
                data.put("companyCode", map.get("compCode"));
                // 判断是否已存在
                String id = existsBizObject(data, CustomSchemaCode.COMPANY_ARCHIVES_BASE);
                if (StringUtils.isNotEmpty(id)) {
                    data.put("id", id);
                }
                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.COMPANY_ARCHIVES_BASE, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("公司级档案落实点检汇总记录 基础表数据新增成功");

                // 删除下级档案
                String fileCodeStr = map.get("fileCodeStr").toString();
                String sql = "delete from company_archives_base where id in (select a.id from ( select id from company_archives_base\n" +
                        "where fileCodeStr like '" + fileCodeStr + "%' and fileCodeStr != '"+fileCodeStr+"'\n" +
                        ") as a)";
                sqlService.update(sql);

                // 调用存储过程
                callCompanyArchivesProcess(id);
            } catch (Exception e) {
                log.info("公司级档案落实点检汇总记录 基础表数据维护失败，报错信息：{}", e.getMessage());
                log.info("公司级档案落实点检汇总记录 基础表数据操作失败 档案代码={}", map.get("fileCodeStr"));
            }
        }
    }

    /**
     * 调用存储过程
     * ------公司级档案点检汇总
     * [SyncComArchiveCheck]
     *
     * @ComCode nvarchar(100),                    ----公司代码   02
     * @archtypeCode nvarchar(100),            ----档案类型号   01 一级文件  08 记录  09 公共资料
     * @ArchCode nvarchar(100),                ----档案代码
     * @Edit NVARCHAR(10),                ----编修
     * @StudyReq NVARCHAR(10),            ----学习要求
     * @Courseware NVARCHAR(10),            ----课件
     * @exam NVARCHAR(10),            ----试题
     * @Err NVARCHAR(10),            ----错失项
     * @Auth nvarchar(10),            ----授权
     * @Train nvarchar(10),            ----培训
     * @Carryout nvarchar(10),            ----落实
     * @DES nvarchar(300),            ----工作说明
     * @Auditor nvarchar(100)            ----审批人   02.0100 张三
     *  公司级档案点检汇总
     */
    private void callCompanyArchivesProcess(String bizId) {
        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        // 编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.COMPANY_ARCHIVES_BASE);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        // 查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}", map);


        // 调用存储过程
        String companyCode = MapUtils.getString(map, "companyCode", "");// 主责公司代码
        String archtypeCode = MapUtils.getString(map, "archtypeCode", "");// 档案类型号
        String typeCode = MapUtils.getString(map, "fileCodeStr", "");// 档案代码
        String edit = MapUtils.getString(map, "edit", "");// 编修
        String learningReq = MapUtils.getString(map, "learningReq", "");// 学习要求
        String courseware = MapUtils.getString(map, "courseware", "");// 课件
        String questions = MapUtils.getString(map, "questions", "");// 试题
        String missItem = MapUtils.getString(map, "missItem", "");// 错失项
        String empower = MapUtils.getString(map, "empower", "");// 授权
        String train = MapUtils.getString(map, "train", "");// 培训
        String practicable = MapUtils.getString(map, "practicable", "");// 落实
        String jobDescription = MapUtils.getString(map, "jobDescription", "");// 工作说明
        String auditer = MapUtils.getString(map, "auditer", "");// 审批人

        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncComArchiveCheck '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s'",
                companyCode, archtypeCode, typeCode, edit, learningReq, courseware, questions, missItem,empower,train,practicable,jobDescription,auditer);
        log.info("\n==========准备调用存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============存储过程执行完成");
    }

    /**
     * 调用存储过程
     * ------总公司级档案公司点检汇总
     * [SyncComCorpArchCheckSum]
     * @archtypeCode nvarchar(100),            ----档案类型号   01 一级文件  08 记录  09 公共资料
     * @ComCode nvarchar(20),            ----公司代码  02  05  06
     * @ArchCode nvarchar(100),            ----档案代码
     * @Auth nvarchar(10),            ----授权
     * @Train NVARCHAR(10),            ----培训
     * @CarryOut NVARCHAR(10),            ----落实
     * @DES nvarchar(300),            ----工作说明
     * @Auditor nvarchar(100)            ----审批人   02.0100 张三
     */
    private void callHeadOfficeArchives2Process(String bizId) {
        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        // 编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.OFFICE_ARCHIVES_BASE_2);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        // 查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}", map);

        // 调用存储过程
        String archtypeCode = MapUtils.getString(map, "archtypeCode", "");// 档案类型号
        String compCode = MapUtils.getString(map, "compCode", "");// 公司代码
        String typeCode = MapUtils.getString(map, "fileCode", "");// 档案代码
        String empower = MapUtils.getString(map, "empower", "");// 授权
        String train = MapUtils.getString(map, "train", "");// 培训
        String practicable = MapUtils.getString(map, "practicable", "");// 落实
        String jobDescription = MapUtils.getString(map, "jobDescription", "");// 工作说明
        String auditer = MapUtils.getString(map, "auditer", "");// 审批人

        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncComCorpArchCheckSum '%s','%s','%s','%s','%s','%s','%s','%s'",
                archtypeCode, compCode, typeCode, empower, train, practicable, jobDescription, auditer);
        log.info("\n==========准备调用存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============存储过程执行完成");
    }

    /**
     * 调用存储过程
     * ------总公司级档案总公司点检汇总
     * exec   SyncCorpArchCheckSum
     */
    private void callHeadOfficeArchives1Process(String bizId) {
        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        // 编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.OFFICE_ARCHIVES_BASE_1);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        // 查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("入参map={}", map);

        // 调用存储过程
        String archtypeCode = MapUtils.getString(map, "archtypeCode", "");// 档案类型号
        String typeCode = MapUtils.getString(map, "fileCodeStr", "");// 档案代码
        String edit = MapUtils.getString(map, "edit", "");// 编修
        String learningReq = MapUtils.getString(map, "learningReq", "");// 学习要求
        String courseware = MapUtils.getString(map, "courseware", "");// 课件
        String questions = MapUtils.getString(map, "questions", "");// 试题
        String missItem = MapUtils.getString(map, "missItem", "");// 错失项
        String empower = MapUtils.getString(map, "empower", "");// 授权
        String jobDescription = MapUtils.getString(map, "jobDescription", "");// 工作说明
        String auditer = MapUtils.getString(map, "auditer", "");// 审批人

        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncCorpArchCheckSum '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s'",
                archtypeCode, typeCode, edit, learningReq, courseware, questions, missItem, empower, jobDescription, auditer);
        log.info("\n==========准备调用存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============存储过程执行完成");
    }

    /**
     * 查询审批人,返回  员工号+姓名
     *
     * @param bizObject
     * @return
     */
    private String getFileBaseInfoWorkFlowApproval(BizObjectCreatedModel bizObject) {
        WorkflowInstanceModel instanceModel = getWorkflowInstanceFacade().getByObjectId(bizObject.getId());
        List<WorkItemModel> workItems = getWorkflowInstanceFacade().getWorkItems(instanceModel.getId(), true);
        final String finalActivityCode = "Activity8";
        Optional<WorkItemModel> first = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode)).findFirst();
        String participant = null;
        if (first.isPresent()) {
            participant = first.get().getParticipant();
        }
        if (participant == null) {
            participant = bizObject.getCreater().getId();
        }
        UserModel user = getOrganizationFacade().getUser(participant);
        return new StringBuilder(user.getEmployeeNo()).append("　").append(user.getName()).toString();
    }


    /**
     * 判断是否已存在
     *
     * @return
     */
    private String existsBizObject(Map data, String schemaCode) {

        String tableName = getBizObjectFacade().getTableName(schemaCode);

        StringBuilder sql = new StringBuilder("select id  from ").append(tableName)
                .append(" where fileCodeStr='").append(data.get("fileCodeStr")).append("'")
                .append(";");
        Map<String, Object> map = sqlService.getMap(sql.toString());
        return (String) map.get("id");
    }

    /**
     * 设置基础表数据
     *
     * @param bizObject 主表数据
     * @param map       子表数据
     * @param auditer   审批人
     * @return
     */
    public static Map<String, Object> fileInfoBaseMap(BizObjectCreatedModel bizObject, Map<String, Object> map, String auditer) {
        // 审批人,审批时间
        map.put("applicant", bizObject.get("applicant"));
        map.put("auditer", auditer);
        map.put("time", new Date());
        map.remove("rowStatus");
        map.remove("id");
        return map;
    }
}
